/**
 * 深拷贝，包括函数
 * @param obj 要拷贝的对象
 * @returns 拷贝后的对象
 */
export default function deepClone<T>(obj: T): T {
  if (obj === null || typeof obj !== 'object') {
    return obj
  }

  // Handling Date
  if (obj instanceof Date) {
    return new Date(obj.getTime()) as unknown as T
  }

  // Handling Array
  if (Array.isArray(obj)) {
    const arrCopy = [] as unknown as T[]
    for (let i = 0; i < obj.length; i++) {
      arrCopy[i] = deepClone(obj[i])
    }
    return arrCopy as unknown as T
  }

  // Handling Function
  if (typeof obj === 'function') {
    const funcCopy = function (this: any, ...args: any[]) {
      return (obj as Function).apply(this, args)
    }
    return funcCopy as unknown as T
  }

  // Handling Object
  const clonedObj = {} as T
  for (const key in obj) {
    if (Object.prototype.hasOwnProperty.call(obj, key)) {
      clonedObj[key] = deepClone((obj as any)[key])
    }
  }

  return clonedObj
}
